#include "rcc.h"

/**********************************时钟树配置.C*******************************
  ****************************************************************************
  * 编写者：  				lxq
  * 最后修改日期：    2020-04-10
	* 修改记录：
	* 		2020-04-09	初次编写
	* 		2020-04-10 	重命名SetSysClockToHSE(uint32_t pllmul)函数为RCC_HSETREE_Config(uint32_t pllmul)
	*									重命名SetSysClockToHSI(uint32_t pllmul)函数为RCC_HSITREE_Config(uint32_t pllmul)
	****************************************************************************
********************************************************************************/



//设置内部时钟源HSE作为系统的时钟来源
//可以进行系统时钟的倍频
void RCC_HSETREE_Config(uint32_t pllmul)
{
	__IO uint32_t HSECounter = 0,HSEStatus = 0;
	
	//复位所有RCC外设
	RCC_DeInit();
	//使能HSE
	RCC_HSEConfig(RCC_HSE_ON);
	
	//等待HSE就绪
	HSEStatus = RCC_WaitForHSEStartUp();
	//就绪成功
	if (HSEStatus == SUCCESS){
		//使能FLASH预存取缓冲区
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
		//设置SYSCLK周期和FLASH访问时间比例
		//0:0M<SYSCLK<=24M
		//1:24M<SYSCLK<=48M
		//2:48M<SYSCLK<=72M
		FLASH_SetLatency(FLASH_Latency_2);
		
		//AHB:HCLK=SYSCLK
		RCC_HCLKConfig(RCC_SYSCLK_Div1);
		//APB2:PCLK2=HCLK
		RCC_PCLK2Config(RCC_SYSCLK_Div1);
		//APB1:PCLK1=HCLK/2
		RCC_PCLK1Config(RCC_HCLK_Div2);
		//PLLCLK=8MHZ*pllmul
		RCC_PLLConfig(RCC_PLLSource_HSE_Div1, pllmul);
		//如果仿真需要降频则使用下面这个 PLLCLK=4MHZ*pllmul
		//RCC_PLLConfig(RCC_PLLSource_HSE_Div2, pllmul);
		
		//开启PLL
		RCC_PLLCmd(ENABLE);
		//等待PLL稳定
		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
		//SYSCLK=PLLCLK
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
		//等待切换完成
		while(RCC_GetSYSCLKSource() != 0x08);
		
	}
	else{
		//HSE开启失败
		while(1);
	}
}

//设置内部时钟源HSI作为系统的时钟来源
void RCC_HSITREE_Config(uint32_t pllmul)
{
	__IO uint32_t HSIStatus = 0;
	
	//复位所有RCC外设
	RCC_DeInit();
	//使能HSI
	RCC_HSICmd(ENABLE);
	
	//等待HSI就绪
	HSIStatus = RCC->CR & RCC_CR_HSIRDY;
	//就绪成功
	if (HSIStatus == RCC_CR_HSIRDY){
		//使能FLASH预存取缓冲区
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
		//设置SYSCLK周期和FLASH访问时间比例
		//0:0M<SYSCLK<=24M
		//1:24M<SYSCLK<=48M
		//2:48M<SYSCLK<=72M
		FLASH_SetLatency(FLASH_Latency_2);
		
		//AHB:HCLK=SYSCLK
		RCC_HCLKConfig(RCC_SYSCLK_Div1);
		//APB2:PCLK2=HCLK
		RCC_PCLK2Config(RCC_SYSCLK_Div1);
		//APB1:PCLK1=HCLK/2
		RCC_PCLK1Config(RCC_HCLK_Div2);
		//PLLCLK=4MHZ*pllmul
		RCC_PLLConfig(RCC_PLLSource_HSI_Div2, pllmul);
		
		//开启PLL
		RCC_PLLCmd(ENABLE);
		//等待PLL稳定
		while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
		//SYSCLK=PLLCLK
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
		//等待切换完成
		while(RCC_GetSYSCLKSource() != 0x08);
		
	}
	else{
		//HSI开启失败
		while(1);
	}
}



//PA8复用做MCO引脚，可以观测系统时钟
void GPIO_MCO_Config(void)
{
	//GPIOA时钟使能
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStruct;
	
	//初始化红色GPIO
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
}

